#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "vector.h"

static int vectorExtend(Vector* vector);

int vectorInitCompare(Vector* vector, int elemSize, CompareFn compare) {
    vector->data = malloc(elemSize * VECTOR_INIT_SIZE);
    if(!vector->data) {
        fprintf(stderr, "vectorInit内存分配失败！\n");
        return 0;
    }
    vector->elementSize = elemSize;
    vector->capacity = VECTOR_INIT_SIZE;
    vector->size = 0;
    vector->compare = compare;
    return 1;
}

int vectorInit(Vector* vector, int elemSize) {
    vectorInitCompare(vector, elemSize, NULL);
}

int vectorAppend(Vector* vector, void* data) {
    if(isFull(vector)) {
        if(!vectorExtend(vector)) {
            fprintf(stderr, "vectorAppend数组扩展失败！\n");
            return 0;
        }
    }
    memcpy(vectorGet(vector, vector->size++), data, vector->elementSize);
    return 1;
}

void* vectorGet(Vector* vector, int idx) {
    if(idx >= vector->capacity) {
        fprintf(stderr, "vectorGet索引%d不能大于等于数组容量%d\n", idx, vector->capacity);
        return NULL;
    }
    void* ptr = (char*) vector->data + idx * vector->elementSize;
    // printf("vectorGet offset: %d, idx: %d, size: %d, ptr: %p, start: %p\n", idx * vector->elementSize, idx, vector->elementSize, ptr, vector->data);
    return ptr;
}

void* vectorRemove(Vector* vector, int idx) {
    uint8_t* tmp = malloc(vector->elementSize);
    void* target = vectorGet(vector, idx);
    memcpy(tmp, target, vector->elementSize);
    // 000,111,222,333,444,555
    for (size_t i = 0; i < (vector->size - idx) * vector->elementSize; i++)
    {
        *(char*)target = *((char*)target + vector->elementSize);
    }
    vector->size--;
    return tmp;
}

int vectorFindFirst(Vector* vector, void* data) {
    for (size_t i = 0; i < vector->size; i++)
    {
        if(vector->compare(data, vectorGet(vector, i)) == 0)
            return i;
    }
    return -1;
}

int vectorFindLast(Vector* vector, void* data) {
    for (size_t i = vector->size - 1; i >= 0; i--)
    {
        if(vector->compare(data, vectorGet(vector, i)) == 0)
            return i;
    }
    return -1;
}

bool isEmpty(Vector* vector) {
    return vector->size == 0;
}

bool isFull(Vector* vector) {
    return vector->size == vector->capacity;
}

static int vectorExtend(Vector* vector) {
    int newCapacity = vector->capacity * 2;
    void* data = realloc(vector->data, newCapacity * vector->elementSize);
    if(!data) {
        fprintf(stderr, "vectorExtend扩展内存失败！\n");
        return 0;
    }
    vector->data = data;
    vector->capacity = newCapacity;
    return 1;
}
